//
//  ILGApplePay.m
//  ILGDemo
//
//  Created by HappyWork on 2019/2/14.
//  Copyright © 2019 Happy. All rights reserved.
//

#import "ILGApplePay.h"

#import <StoreKit/StoreKit.h>

static NSString * const ILGPayErrorDomain = @"com.ILGPay.error";

@interface ILGApplePay () <SKPaymentTransactionObserver, SKProductsRequestDelegate> {
    NSString *_productID;
    NSString *_orderID;
}
@property (nonatomic, strong) NSArray *productIdentifierArr;

@property (nonatomic, strong) NSArray *productArr; //苹果商品列表

@property (nonatomic, copy, readonly) NSString *receipt; // 内购票据

@property (nonatomic, strong) NSMutableDictionary *transactionDict;

@end


@implementation ILGApplePay

- (void)addTransactionObserver {
    [[SKPaymentQueue defaultQueue] addTransactionObserver:self];
}

- (void)configureProductIdentifierArr:(NSArray *)array {
    _productIdentifierArr = array;
}

- (void)pay:(NSString *)productId orderId:(NSString *)orderId {
    NSString *errorMsg = nil;
    if (orderId.length == 0 ||
        productId.length == 0) {
        errorMsg = [NSString stringWithFormat:@"参数异常，orderId=%@，productId=%@", orderId, productId];
    }
    
    if (![SKPaymentQueue canMakePayments]) {
        errorMsg = @"此设备不支持内购支付";
    }
    
    if (errorMsg.length) {
        NSError *error = [NSError errorWithDomain:ILGPayErrorDomain code:-1 userInfo:@{NSLocalizedDescriptionKey:errorMsg}];
        [self p_transactionCompleted:orderId error:error];
        return;
    }
    

    _productID = productId;
    _orderID = orderId;
    
    if (self.productArr.count == 0) {
        [self p_requestProducts];
    } else {
        SKProduct *product = [self p_currentProduct:_productID];
        [self p_buyProductIdentifier:product platformOrderId:_orderID];
    }
}

- (void)finishTransaction:(NSString *)orderId {
    if (orderId.length == 0) {
        return;
    }
    
    SKPaymentTransaction *transaction = self.transactionDict[orderId];
    if (transaction) {
        [[SKPaymentQueue defaultQueue] finishTransaction:transaction];
        [self.transactionDict removeObjectForKey:orderId];
    }
}


#pragma mark - getter

- (NSString *)receipt {
    NSData *receiptData = [NSData dataWithContentsOfURL:[[NSBundle mainBundle] appStoreReceiptURL]];
    NSString *receipt = [receiptData base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed];
    
    return receipt;
}

- (NSArray *)productIdentifierArr {
    if (!_productIdentifierArr) {
        NSDictionary *plistDic = [[NSBundle mainBundle] infoDictionary];
        NSString *bundleId = [plistDic objectForKey:@"CFBundleIdentifier"];
        NSMutableArray *tempMutArr = [NSMutableArray array];
        for (int index = 1; index <= 6; index++) {
            [tempMutArr addObject:[bundleId stringByAppendingString:[NSString stringWithFormat:@".diamond%d", index]]];
        }
        
        return tempMutArr;
    } else {
        return _productIdentifierArr;
    }
}

- (NSMutableDictionary *)transactionDict {
    if (!_transactionDict) {
        _transactionDict = [NSMutableDictionary dictionary];
    }
    return _transactionDict;
}


#pragma mark - delegate
#pragma mark SKRequestDelegate
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response {
    self.productArr = response.products;
    
    if (self.productArr.count == 0) {
        NSError *error = [NSError errorWithDomain:ILGPayErrorDomain code:-1 userInfo:@{NSLocalizedDescriptionKey:@"向苹果服务器请求回来的商品列表为空"}];
        
        [self p_transactionCompleted:_orderID error:error];
    } else {
        SKProduct *product = [self p_currentProduct:_productID];
        [self p_buyProductIdentifier:product platformOrderId:_orderID];
    }
}

- (void)request:(SKRequest *)request didFailWithError:(NSError *)error {
    NSString *errMsg = error.localizedDescription ? :@"向苹果服务器请求商品列表失败";
    NSInteger errCode = (error.code != 0)?error.code:-1;
    NSError *tmpError = [NSError errorWithDomain:ILGPayErrorDomain code:errCode userInfo:@{NSLocalizedDescriptionKey:errMsg}];
    
    [self p_transactionCompleted:_orderID error:tmpError];
}

#pragma mark SKPaymentTransactionObserver
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions {
    for (SKPaymentTransaction *transaction in transactions)
    {
        switch (transaction.transactionState)
        {
            case SKPaymentTransactionStatePurchasing:
                [self handleTransactionForPurchasingState:transaction];
                break;
            case SKPaymentTransactionStatePurchased:
                [self handleTransactionForPurchasedState:transaction];
                break;
            case SKPaymentTransactionStateFailed:
                [self handleTransactionForFailedState:transaction];
                break;
            case SKPaymentTransactionStateRestored:
                [self handleTransactionForRestoredState:transaction];
                break;
            default:
                break;
        }
    }
}


#pragma mark - 处理不同状态的transaction
- (void)handleTransactionForPurchasingState:(SKPaymentTransaction *)transaction {
    [self p_saveLastOrderAddedToPaymentQueue:_orderID];
}

- (void)handleTransactionForPurchasedState:(SKPaymentTransaction *)transaction {
    NSString *orderId = [self p_currentOrderId:transaction];
    
    if (orderId.length == 0) {
        [[SKPaymentQueue defaultQueue] finishTransaction:transaction];
    } else {
        [self.transactionDict setObject:transaction forKey:orderId];
        [self p_transactionCompleted:orderId error:nil];
    }
}

- (void)handleTransactionForFailedState:(SKPaymentTransaction *)transaction {
    NSString *orderId = [self p_currentOrderId:transaction];
    [self p_transactionCompleted:orderId error:transaction.error];
    
    [[SKPaymentQueue defaultQueue] finishTransaction:transaction];
}

- (void)handleTransactionForRestoredState:(SKPaymentTransaction *)transaction {
    [[SKPaymentQueue defaultQueue] finishTransaction:transaction];
}


#pragma mark - data

- (NSString *)transactionIdentifierForOrder:(NSString *)orderId {
    if (orderId.length == 0) {
        return nil;
    }
    
    SKPaymentTransaction *transaction = self.transactionDict[orderId];
    return transaction.transactionIdentifier;
}

- (void)p_saveLastOrderAddedToPaymentQueue:(NSString *)orderId {
    if (orderId.length) {
        [[NSUserDefaults standardUserDefaults] setObject:orderId forKey:@"ilgLastOrderId"];
    }
}
- (NSString *)p_lastOrderAddedToPaymentQueue {
    return [[NSUserDefaults standardUserDefaults] objectForKey:@"ilgLastOrderId"];
}

- (NSString *)p_currentOrderId:(SKPaymentTransaction *)transaction {
    NSString *orderId = transaction.payment.applicationUsername;
    
    if (orderId.length == 0) {
        orderId = [self p_lastOrderAddedToPaymentQueue];
    }
    
    if (orderId.length == 0) {
        orderId = _orderID;
    }
    
    return orderId;
}


#pragma mark - other

- (SKProduct *)p_currentProduct:(NSString *)productIdentifier {
    for (SKProduct *product in self.productArr) {
        if ([product.productIdentifier isEqualToString:productIdentifier]) {
            return product;
        }
    }
    return nil;
}

// 向苹果服务器发送请求商品列表请求
- (void)p_requestProducts {
    NSMutableSet *productIdentifiers = [NSMutableSet set];
    if (self.productIdentifierArr.count > 0) {
        for (int i=0; i< self.productIdentifierArr.count; i++) {
            [productIdentifiers addObject:self.productIdentifierArr[i]];
        }
    }
    SKProductsRequest *request = [[SKProductsRequest alloc]initWithProductIdentifiers:productIdentifiers];
    request.delegate = self;
    [request start];
}

// 商家服务器下单成功后，调用苹果支付接口
- (void)p_buyProductIdentifier:(SKProduct *)product platformOrderId:(NSString *)platformOrderId {
    if (!product) {
        NSError *error = [NSError errorWithDomain:ILGPayErrorDomain code:-1 userInfo:@{NSLocalizedDescriptionKey:@"苹果服务器请求回来的商品列表中不存在此产品"}];
        [self p_transactionCompleted:_orderID error:error];
        return;
    }
    
    SKMutablePayment *payment = [SKMutablePayment paymentWithProduct:product];
    payment.applicationUsername = platformOrderId;
    
    [[SKPaymentQueue defaultQueue] addPayment:payment];
}

- (void)p_transactionCompleted:(NSString *)orderId error:(NSError *)error {
    if ([self.delegate respondsToSelector:@selector(applePayComplete:error:)]) {
        NSString *transactionIdentifier = [self transactionIdentifierForOrder:orderId];
        NSString *receipt = [self receipt];
        
        transactionIdentifier = transactionIdentifier.length?transactionIdentifier:@"";
        receipt = receipt.length ? receipt:@"";
        orderId = orderId.length ? orderId:@"";
        NSDictionary *result = @{@"orderId":orderId,
                                 @"receipt":receipt,
                                 @"transactionIdentifier":transactionIdentifier
                                 };

        [self.delegate applePayComplete:result error:error];
    }
}

@end
